
-- 跨服精英赛 数据
local CSEliteMatch = class("CSEliteMatch")
local CSEliteMatchSeasonInfo = import(".CSEliteMatchSeasonInfo")
local BoxItemVo = require("app.reward.models.BoxItemVo")
local PvpDuelMemberVo = require("app.pvp.models.PvpDuelMemberVo")

local _TEST = true
local table_insert = table.insert
local table_sort = table.sort

function CSEliteMatch:ctor()
    self.crossCombatInfo = nil
    self.crossCombatStatus = nil
    self._duelTeamInfo = nil
    self._lastSeasonChampionInfo = {}
    self._lastGetRankListTime = nil -- 上一次拉取排行榜的时间
    self.crossCombatMyRank = {} -- 我的排名
end

function CSEliteMatch:getCrossCombatInfo()
    return self.crossCombatInfo
end

function CSEliteMatch:getPlayInfoById(id)
    return self.crossCombatInfo:getPlayInfoById(id)
end

function CSEliteMatch:getState()
    return self.crossCombatInfo:getState()
end

function CSEliteMatch:getTeammates()
    return self.crossCombatInfo:getTeammates()
end

-- 精英赛匹配过程中
function CSEliteMatch:isInEliteMatch()
    if self.crossCombatStatus then
        return self.crossCombatStatus.state == "matching"
    end
    return false
end

function CSEliteMatch:getCrossCombatStatus()
    return self.crossCombatStatus
end

function CSEliteMatch:isOpen()
    return self.crossCombatStatus.isOpen
end

function CSEliteMatch:getOpenPlayId()
    return self.crossCombatStatus.playId
end

function CSEliteMatch:getStartTime()
    return self.crossCombatStatus.startTime
end

function CSEliteMatch:getEndTime()
    return self.crossCombatStatus.endTime
end

-- 此玩法当前是否在开启时间段内
function CSEliteMatch:isOpenByPlayId(id)
    if id == self.crossCombatStatus.playId then
        return self.crossCombatStatus.isOpen
    end
    return false
end

-- 此玩法今天是否开放
function CSEliteMatch:isTodayOpenByPlayId(id)
    if id == self.crossCombatStatus.playId then
        return true
    else
        return false
    end
end

function CSEliteMatch:getEliteMatchDuelInfo()
    return self._duelTeamInfo
end

function CSEliteMatch:getMyRankByPlayId(id)
    return self.crossCombatMyRank[id]
end

function CSEliteMatch:clearHistoryChampion()
    self._lastSeasonChampionInfo = {}
end
----------------------response-----------------------
-- 服务器通知开放信息
function CSEliteMatch:onCombatCrossOpenInfo(msg)
    -- 通知精英赛结束，正在匹配中的话弹出提示
	if not msg.isOpen then
		if self.crossCombatStatus and self.crossCombatStatus.isOpen and self.crossCombatStatus.state == "matching" then
			display.pushToast(L("challengeTips12"))
		end
	end

	local data = {}
	data.isOpen = msg.isOpen
	data.playId = msg.playId
	data.startTime = msg.startTime
	data.endTime = msg.endTime
	data.state = msg.state
	data.startMatchStamp = msg.startMatchStamp
	if not data.isOpen then
		data.state = "idle"
	end
	-- dump(data, "onCombatCrossOpenInfo")
    self.crossCombatStatus = data
    if self.crossCombatInfo then
        self.crossCombatInfo:setState(msg.state)
		EM:notify(ViewEvent.CSElite_CrossCombatMatchUpdate)
	end

	-- 同步更新state
	self:updateChallengeState(msg.state, msg.startMatchStamp)
end

-- 战斗结果
function CSEliteMatch:onCrossCombatBattleResult(msg)
    self.crossCombatInfo = CSEliteMatchSeasonInfo.new(msg.seasonInfo)
    local rewards = {}
    if msg.hasWon then
        for i, data in ipairs(msg.itemReward) do
            local reward = UD:parseLootToBagItem(data)
            if reward then
                rewards[#rewards+1] = {}
                rewards[#rewards].itemData = reward
            end
        end
        if msg.expReward > 0 then
            local expId = 151
            if msg.type == Enums.TeamTarget.eliteMatchArena then            
                expId = 151
            elseif msg.type == Enums.TeamTarget.eliteMatchDuel then
                expId = 152
            end
            local info = table.concat({expId, 0, msg.expReward}, "|")
            local expData = UD:parseRewardToBagItem(info)
            if expData then
                rewards[#rewards+1] = {}
                rewards[#rewards].itemData = expData
            end
        end
    end
    if msg.type == Enums.TeamTarget.eliteMatchArena then
        app:sendMsg("PvpController", "openChallengeResultView", msg.type, msg.hasWon, rewards)
    elseif msg.type == Enums.TeamTarget.eliteMatchDuel then
        app:sendMsg("PvpEliteController", "openEliteMatchWinView", {win = msg.hasWon, rewards = rewards, type = msg.type})
    end
end

-- 匹配返回(不准备也返回此消息)
function CSEliteMatch:onCombatCrossMatch(msg)
    -- 关闭组队投票界面
    app:sendMsg("NewTeamReadyAndSettingController", "closeView")

    -- 消息提示
    local reason = msg.reason
    local tipStr
    if reason == "LeaderCancel" then
        tipStr = string.format(L("CrossServerTips10"), L("CrossServerTips7"))
    elseif reason == "MemberQuit" then
        tipStr = L("CrossServerTips11")
    elseif reason == "EnterTeam" then
        tipStr = L("CrossServerTips12")
    elseif reason == "MemberAdd" then
        tipStr = L("CrossServerTips13")
    elseif reason == "LeaveTeam" then
        tipStr = L("CrossServerTips20")
    end
    if tipStr then
        local tipParams = {remindId=Constant.FUNC_TYPE_CROSS_MATCH, params=tipStr}
        UIHandler:showThirdLevelTips(tipParams)
    end
    
    if not msg or not msg.ok then return end

    if self.crossCombatInfo then
        self.crossCombatInfo:readMatchInfo(msg.matchInfo)
		EM:notify(ViewEvent.CSElite_CrossCombatMatchUpdate)
    end
    -- 同步更新state
	self:updateChallengeState(msg.matchInfo.state, msg.matchInfo.startStamp)
end

-- 取消匹配返回
function CSEliteMatch:onCombatCrossCancel(msg)
    if not msg or not msg.ok then return end
	if self.crossCombatInfo then
        self.crossCombatInfo:readMatchInfo(msg.matchInfo)
		EM:notify(ViewEvent.CSElite_CrossCombatMatchUpdate)
    end
    -- 同步更新state
	self:updateChallengeState(msg.matchInfo.state, msg.matchInfo.startStamp)
end

function CSEliteMatch:onCombatCrossCheckMatchCondition(msg)
	if msg and msg.ok then
		executeFunc(self._checkElietMatchConditionCB)
	end
	self._checkElietMatchConditionCB = nil
end

-- 准备信息——游戏服通知客户端准备
function CSEliteMatch:onCrossCombatPrepareNotify(msg)
    self._crossCombatPrepareNotify = msg
    if self.crossCombatInfo then
        self.crossCombatInfo:setState("prepare")
        EM:notify(ViewEvent.CSElite_CrossCombatMatchUpdate)
    end
    -- 设置结束时间
    if msg.readyNum == 0 then
        self._crossCombatPrepareEndTime = app.session:getServerTime() + 30 --倒计时30秒
    end
    -- 同步更新state
	self:updateChallengeState("prepare")
    -- 边界条件判断
	if BattleManager:isInBattle() or BattleManager:isWaitBattle() then -- 如果在战斗中，退出战斗
		-- BattleManager:goOutBattle()
		BattleUIEvent:dispatchEvent(BattleUIEvent.TYPE.BATTLE_ESCAPE)
	elseif StoryManager:isEnterStoryMode() then -- 在剧情中,强制结束当前剧情
		-- display.pushToast(L("挑战赛匹配成功，请打开准备界面"))
		StoryManager:forceExitCurStory()
	else 
		-- 如果正在进行一些操作，就stop，停止追踪
		app:getLaunchCtl():endCharacterMove()
		-- 关闭宝箱界面
		app:sendMsg("BoxController", "closeView")
	end
    app:sendMsg("PvpChallengeController", "updateChallengePrepare", msg)
end

-- 精英赛 获取prepareNotify
function CSEliteMatch:getCrossCombatPrepareNotify()
    return self._crossCombatPrepareNotify
end

-- 精英赛 获取准备结束时间
function CSEliteMatch:getCrossCombatPrepareEndTime()
    if not self._crossCombatPrepareEndTime then
        self._crossCombatPrepareEndTime = app.session:getServerTime() + 30
    end
    return self._crossCombatPrepareEndTime
end

-- 惩罚信息——游戏服通知客户端惩罚
function CSEliteMatch:onCrossCombatPunishNotify(msg)
    if not msg.mySelf then
        local tipParams = {remindId=Constant.FUNC_TYPE_CROSS_MATCH, params=L("CrossServerTips14")}
        UIHandler:showThirdLevelTips(tipParams)
    end
	if self.crossCombatInfo then
        self.crossCombatInfo:readMatchInfo(msg.matchInfo)
        EM:notify(ViewEvent.CSElite_CrossCombatMatchUpdate)
	end
	-- 同步更新state
	print("punishNotify:", msg.matchInfo.state, msg.matchInfo.startStamp)
	self:updateChallengeState(msg.matchInfo.state, msg.matchInfo.startStamp)
end

-- 精英决斗赛查询阵容信息
function CSEliteMatch:onQueryNowTeamInfo(msg)
    self._duelTeamInfo = PvpDuelMemberVo.new(msg)
    EM:notify(ViewEvent.CSElite_onBattlePartnerChange, self._duelTeamInfo)
end

-- 精英赛 更新state, startMatchStamp只在state == "matching" 才有效
function CSEliteMatch:updateChallengeState(state, startMatchStamp)
    if not startMatchStamp then startMatchStamp = 0 end

    if self.crossCombatStatus then
        self.crossCombatStatus.state = state
        self.crossCombatStatus.startMatchStamp = startMatchStamp

        -- 通知到 tasktrackview 里，是否显示精英赛对应的item
        EM:notify("onTaskTrackChange")
        EM:notify(ViewEvent.CSElite_MatchStateUpdate, self.crossCombatStatus.playId)
        
        app:sendMsg("TeamModel", "updateTeamCrossMatch", self:getOpenPlayId(), self:isInEliteMatch())
    end

    -- -- 关闭准备界面
    if state ~= "prepare" then
        self._crossCombatPrepareNotify = nil
        app:sendMsg("PvpChallengeController", "closeChallengePrepare")
    end

end

----------------------requesrt-----------------------
-- 获取玩法信息
function CSEliteMatch:C2S_GetCrossCombatInfo(cb)
    -- print("C2S_GetCrossCombatInfo------------->>>>获取玩法信息")
    app.session:request("pb_combatcross.C2S_GetCrossCombatInfo", {}, function(msg)
        -- dump(msg, "S2C_GetCrossCombatInfo")
        if msg.seasonInfo then
            self.crossCombatInfo = CSEliteMatchSeasonInfo.new(msg.seasonInfo)
            if self.crossCombatInfo then
                EM:notify(ViewEvent.CSElite_CrossCombatInfo, self.crossCombatInfo)
                app:sendMsg("PvpEliteController", "onEliteMatchInfoUpdate")
            end
        end
        if cb then
            executeFunc(cb)
        end
    end)
end

-- 开始匹配
function CSEliteMatch:C2S_CombatCrossMatch(id)
    -- print("C2S_CombatCrossMatch--------->>>>开始匹配")
    if self:isOpen() then
        app.session:request("pb_combatcross.C2S_CombatCrossMatch", {playID = id})
    else
        display.pushToast(L("ErrEventNotStart"))
    end
end

-- 取消匹配
function CSEliteMatch:C2S_CombatCrossCancel()
    -- print("C2S_CombatCrossCancel--------->>>>取消匹配")
    app.session:request("pb_combatcross.C2S_CombatCrossCancel", {})
end

-- 检查匹配条件
function CSEliteMatch:C2S_CombatCrossCheckMatchCondition(cb)
    -- print("C2S_CombatCrossCheckMatchCondition--------->>>>检查匹配条件")
    self._checkElietMatchConditionCB = cb 
    app.session:request("pb_combatcross.C2S_CombatCrossCheckMatchCondition", {})
end

-- 领取赛季奖励
function CSEliteMatch:C2S_GetCrossCombatSeasonReward(id)
    -- print("C2S_GetCrossCombatSeasonReward-------->>>>领取赛季奖励")
    app.session:request("pb_combatcross.C2S_GetCrossCombatSeasonReward", {playID = id}, function(msg)
        local items = {}
        local item
        for i,v in ipairs(msg.rewardList) do
            -- 凑出BoxView的数据
            items[i] = BoxItemVo.new({loot = v})
        end
        items = table.randomCnt(items)
        app:sendMsg("BoxController", "onOpenBox", items)
    end, nil, function(errMsg)
        app:sendMsg("BoxController", "closeView")
    end)
end

-- 准备或放弃准备
function CSEliteMatch:C2S_CrossCombatPrepare(b)
    -- print("C2S_CrossCombatPrepare---------->>>准备或放弃准备")
    app.session:request("pb_combatcross.C2S_CrossCombatPrepare", {prepare = b}, function(msg)     
    end)
end

-- 查询当前精英决斗赛阵容
function CSEliteMatch:C2S_QueryNowTeamInfo()
    -- print("C2S_QueryNowTeamInfo------------>>>>查看精英决斗赛阵容")
    app.session:request("pb_combatcross.C2S_QueryNowTeamInfo", {})
end

-- 精英决斗赛上下阵随从
function CSEliteMatch:C2S_OnBattlePartnerChange(partnerId, b)
    -- print("C2S_OnBattlePartnerChange--------->>>>精英决斗赛上下阵随从", partnerId, b)
    app.session:request("pb_combatcross.C2S_OnBattlePartnerChange", {id = partnerId, onBattle =b}, function(msg)
        if msg.ok then
            -- print("Success------------>>>>")
        end
    end)
end

-- 拉取上赛季冠军信息
function CSEliteMatch:C2S_GetHistoryChampion(playId)
    -- print("C2S_GetHistoryChampion---------->>>>拉取上赛季冠军信息", playId)
    if not self._lastSeasonChampionInfo[playId] then
        self._lastSeasonChampionInfo[playId] = {}
        app.session:request("pb_combatcross.C2S_GetHistoryChampion", {playType = playId}, function(msg)
            -- dump(msg, "S2C_GetHistoryChampion")
            if msg.playType == playId then
                self._lastSeasonChampionInfo[msg.playType] = msg
            end
            EM:notify(ViewEvent.CSElite_LastSeasonChampionInfo, self._lastSeasonChampionInfo[playId])
        end)
    else
        EM:notify(ViewEvent.CSElite_LastSeasonChampionInfo, self._lastSeasonChampionInfo[playId])
    end
end

-- 拉取排行榜获取我的排名
function CSEliteMatch:C2S_WorldRankList(aID)
   if self._lastGetRankListTime and self.crossCombatMyRank[aID] then
        local serverTime = app:getServerTime()
        if serverTime - self._lastGetRankListTime < 2*60 then --两分钟拉一次排行榜
            EM:notify(ViewEvent.CSElite_MyRankUpdate, aID, self.crossCombatMyRank[aID])
            return
        end
    end
    app.session:request("pb_rank.C2S_WorldRankList", {id=protobuf.enum_name("pb_rank.RANK_ID", aID)}, function(msg)
        self._lastGetRankListTime = app:getServerTime()
        self.crossCombatMyRank[aID] = msg.myRank
        EM:notify(ViewEvent.CSElite_MyRankUpdate, aID, self.crossCombatMyRank[aID])  
    end)
end

return CSEliteMatch